﻿
using LS.Nc6.Core;
using System.Collections.Generic;

namespace LS.Nc6.Application.Cms
{
    /// <summary>
    /// 内容表
    /// </summary>
    public class CmsContentService : BaseService<CmsContentEntity>,ICmsContentService, ITransient
    {
        public async Task<Tuple<List<dynamic>, int, int>> PageDynamicLeftJoinList(Expression<Func<CmsContentEntity, CmsChannelEntity, bool>> expression, int page, int limit, 
            Expression<Func<CmsContentEntity, CmsChannelEntity, object>> expressionOrder, Expression<Func<CmsContentEntity, CmsChannelEntity, dynamic>> expressionSelect)
        {
            RefAsync<int> totalCount = 0;
            var items = await DbContext.Instance.Queryable<CmsContentEntity>().LeftJoin<CmsChannelEntity>(expression).OrderByDescending(expressionOrder).Select(expressionSelect).ToPageListAsync(page, limit, totalCount);
            var totalPages = (int)Math.Ceiling(totalCount / (double)limit);
            return new Tuple<List<dynamic>, int, int>(
                 items, (int)totalCount, totalPages
            );

        }

        public async Task<List<long>> GetContentIdsAsync(long channelId)
        {
            return await DbContext.Instance.Queryable<CmsContentEntity>().Where(a => a.ChannelId == channelId).Select(a => a.Id).ToListAsync();
           
        }

        public async Task<int> SetAttr(long id, int top, int recommend, int hot, int color,int attrType)
        {
            return await DbContext.Instance.Updateable<CmsContentEntity>().SetColumnsIF(top==1, a => a.Top == attrType).SetColumnsIF(recommend==1,a => a.Recommend == attrType)
                .SetColumnsIF(hot==1,a => a.Hot == attrType).SetColumnsIF(color == 1,a => a.Color == attrType).Where(a => a.Id == id).ExecuteCommandAsync();
        }

        public async Task<int> SetTaxisToUp(long channelId, long contentId, int isTop)
        {
            var contentTaxisModel=  await DbContext.Instance.Queryable<CmsContentEntity>().Where(a => a.ChannelId == channelId && a.Id == contentId).SingleAsync();
            var result =await DbContext.Instance.Queryable<CmsContentEntity>().Where(a => a.Taxis > contentTaxisModel.Taxis)
                .OrderBy(a => a.Taxis).FirstAsync();
            long higherId = 0;
            int higherTaxis = 0;
            if (result != null)
            {
                higherId = result.Id;
                higherTaxis = result.Taxis;
            }

            if (higherId == 0) return 0;

            await DbContext.Instance.Updateable<CmsContentEntity>().SetColumns(a => a.Taxis == higherTaxis).Where(a => a.Id == contentId).ExecuteCommandAsync();

            await DbContext.Instance.Updateable<CmsContentEntity>().SetColumns(a => a.Taxis == contentTaxisModel.Taxis).Where(a => a.Id == higherId).ExecuteCommandAsync();

            return 1;
        }

        public async Task<int> SetTaxisToDown(long channelId, long contentId, int isTop)
        {
            var contentTaxisModel = await DbContext.Instance.Queryable<CmsContentEntity>().Where(a => a.ChannelId == channelId && a.Id == contentId).SingleAsync();
            var result = await DbContext.Instance.Queryable<CmsContentEntity>().Where(a => a.Taxis < contentTaxisModel.Taxis)
                .OrderByDescending(a => a.Taxis).FirstAsync();
            long lowerId = 0;
            int lowerTaxis = 0;
            if (result != null)
            {
                lowerId = result.Id;
                lowerTaxis = result.Taxis;
            }

            if (lowerId == 0) return 0;

            await DbContext.Instance.Updateable<CmsContentEntity>().SetColumns(a => a.Taxis == lowerTaxis).Where(a => a.Id == contentId).ExecuteCommandAsync();

            await DbContext.Instance.Updateable<CmsContentEntity>().SetColumns(a => a.Taxis == contentTaxisModel.Taxis).Where(a => a.Id == lowerId).ExecuteCommandAsync();

            return 1;
        }

        public  async Task<int> SetArrangeTaxis(long channelId, string attributeName, int IsDesc)
        {
            var taxis = 0;
            List<long> contentIds = new List<long>();
            if (IsDesc==1) //倒叙
            {
                if(attributeName == "Id")
                {
                    contentIds = await DbContext.Instance.Queryable<CmsContentEntity>().Where(a => a.ChannelId == channelId).OrderBy(a => a.Id).Select(a => a.Id).ToListAsync();
                }
                else
                {
                    contentIds = await DbContext.Instance.Queryable<CmsContentEntity>().Where(a => a.ChannelId == channelId).OrderBy(a => a.AddTime).Select(a => a.Id).ToListAsync();
                }
            }
            else
            {
                if (attributeName == "Id")
                {
                    contentIds = await DbContext.Instance.Queryable<CmsContentEntity>().Where(a => a.ChannelId == channelId).OrderByDescending(a => a.Id).Select(a => a.Id).ToListAsync();
                }
                else
                {
                    contentIds = await DbContext.Instance.Queryable<CmsContentEntity>().Where(a => a.ChannelId == channelId).OrderByDescending(a => a.AddTime).Select(a => a.Id).ToListAsync();
                }
            }
            foreach (long id  in contentIds)
            {
                taxis++;
                await DbContext.Instance.Updateable<CmsContentEntity>().SetColumns(a => a.Taxis == taxis).Where(a=>a.Id== id).ExecuteCommandAsync();
            }
            return 1;
        }

        public async Task<int> SetHits(long contentId, int hits, int isAdd)
        {
            
            var content = await GetByIdAsync(contentId);
            if (content == null) return 1;

            if (isAdd == 1)
            {
                content.Hits += hits;
            }
            else
            {
                content.Hits -= hits;
            }
            if (content.Hits < 0) content.Hits = 0;
            await DbContext.Instance.Updateable<CmsContentEntity>().SetColumns(a=>a.Hits== content.Hits).Where(a=>a.Id==contentId).ExecuteCommandAsync();
            return 1;
        }

        public async  Task<int> GetTaxis(long channelId)
        {
           return await DbContext.Instance.Queryable<CmsContentEntity>().Where(a => a.ChannelId == channelId).MaxAsync(a => a.Taxis);
        }

        public async Task<int> SetChecked(long contentId, int state)
        {
           return  await DbContext.Instance.Updateable<CmsContentEntity>().SetColumns(a => a.Checked == state).Where(a => a.Id == contentId).ExecuteCommandAsync();
        }
    }
}
